using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

namespace EGEngine
{
    public class AudioModule : MonoBehaviour
    {
        [SerializeField] private float defaultVoiceVolume;
        [SerializeField] private float defaultSoundVolume;
        [SerializeField] private float defaultMusicVolume;
        [SerializeField] private float defaultFadeOutVolumePercent;
        [SerializeField] private float defaultFadeInTime;
        [SerializeField] private float defaultFadeOutTime;

        public static float VoiceVolume = 1;
        public static float SoundVolume = 1;
        public static float MusicVolume = 1;
        public static float FadeOutVolumePercent = 1;
        public static float FadeInTime = 1;
        public static float FadeOutTime = 1;

        private static string _voiceVolumeKey;
        private static string _soundVolumeKey;
        private static string _musicVolumeKey;

        private static List<AudioAgent> _audioAgents;
        private static Transform _parent;


        public void Init()
        {
            _audioAgents = new List<AudioAgent>();
            _parent = transform;

            VoiceVolume = defaultVoiceVolume;
            SoundVolume = defaultSoundVolume;
            MusicVolume = defaultMusicVolume;
            FadeOutVolumePercent = defaultFadeOutVolumePercent;
            FadeInTime = defaultFadeInTime;
            FadeOutTime = defaultFadeOutTime;
        }

        private static void PlaySync(ResourceLoader loader, string location, EAudioType audioType, bool loop = false,
            bool otherFadeOut = false, bool thisFadeIn = false)
        {
            AudioAgent agent = GetCanUseAgent();
            var volume = GetVolume(audioType);

            agent.PlaySync(loader, location, audioType, volume, loop, thisFadeIn);

            if (otherFadeOut && audioType > 0)
            {
                foreach (var audioAgent in _audioAgents)
                {
                    if (audioAgent.IsUsing && audioAgent.AudioType > audioType)
                    {
                        audioAgent.SetFadeInOut(-1);
                    }
                }
            }
        }

        private static async Task PlayAsync(ResourceLoader loader, string location, EAudioType audioType,
            bool loop = false,
            bool otherFadeOut = false, bool thisFadeIn = false)
        {
            var agent = GetCanUseAgent();
            var volume = GetVolume(audioType);

            await agent.PlayAsync(loader, location, audioType, volume, loop, thisFadeIn);
            
            if (otherFadeOut && audioType > 0)
            {
                foreach (var audioAgent in _audioAgents)
                {
                    if (audioAgent.IsUsing && audioAgent.AudioType > audioType)
                    {
                        audioAgent.SetFadeInOut(-1);
                    }
                }
            }
        }

        private static AudioAgent GetCanUseAgent()
        {
            AudioAgent agent = null;
            foreach (var tempAgent in _audioAgents)
            {
                if (!tempAgent.IsUsing)
                {
                    agent = tempAgent;
                    break;
                }
            }

            if (agent == null)
            {
                agent = AudioAgent.CreateAgent();
                agent.transform.SetParent(_parent);
                agent.transform.localPosition = Vector3.zero;
            }

            return agent;
        }

        private static float GetVolume(EAudioType audioType)
        {
            if (audioType == EAudioType.Voice)
            {
                return VoiceVolume;
            }

            if (audioType == EAudioType.Sound)
            {
                return SoundVolume;
            }

            if (audioType == EAudioType.Music)
            {
                return MusicVolume;
            }

            return 1;
        }
    }
}